<?php

require_once 'dao/admin/session.php';
require_once 'dao/admin/user.php';

class admin_session {

    private static $cookie_key = 'XYX_A_S';

    private static $authorized_session = array();

    public static function get_role(){

        $au_dao = dao_admin_user::getInstance();
        return $au_dao->get_role($uid);

    }

    /**
     * @return mixed uid or false on error
     */
    public static function check($halt = true){
        if(!empty(self::$authorized_session['uid'])){
            $uid = self::$authorized_session['uid'];
        } else {
            $uid = self::_checkSession();
        }

        // if not uid, need login
        if(empty($uid)){
            if($halt){
                self::error('need login', true);
            } 
            return false;
        }

        self::$authorized_session['uid'] = $uid;

        return $uid;
    }

    /**
     * @return mixed uid or false on error
     */
    public static function require_role($role){
        return self::check_role($role, true);
    }

    /**
     * @return mixed uid or false on error
     */
    public static function check_role($role, $halt = false){
        $uid = self::check($halt);
        if(empty($uid)){
            return false;
        }

        $au_dao = dao_admin_user::getInstance();
        $check = $au_dao->check_role($uid, $role);
        if($check){
            return $uid;
        } else {
            if($halt){
                self::error('not authorized as ' . $role);
            }
            return false;
        }
    }


    public static function check_csrf($check_string){
        $s = self::get_csrf_string();
        if($check_string == $s and !empty($s)){
            return true;
        } else {
            echo 'csrf attact detected.';
            error_log( 'csrf attact detected.');
            exit;
        }
    }

    public static function get_csrf_string(){
        return self::get_cookie('csrf'); 
    }

    public static function set($uid){

        // generate session_key
        $session_key = md5(uniqid($uid.'_xq', true)) . '_' . $uid;
        $csrf = md5(uniqid($session_key, true));

        self::set_cookies(array(
            'session_key' => $session_key,
            'csrf' => $csrf,
        ));

        // set db
        $as_dao = dao_admin_session::getInstance();
        $as_dao->set($session_key, $uid);
    }

    public static function delete($uid){

        self::set_cookies(array(
            'session_key' => null,
            'csrf' => null,
        ));

        // delete db
        $as_dao = dao_admin_session::getInstance();
        $as_dao->delete($uid);
    }

    public static function _checkSession(){
        $session_key = self::get_cookie('session_key');
        if(empty($session_key)){
            return false;
        }

        $as_dao = dao_admin_session::getInstance();
        $uid = $as_dao->get($session_key);
        if(empty($uid)){
            return false;
        }

        return $uid;
    }

    public static function get_cookie($name){
        $cookies = self::get_cookies();
        if(isset($cookies[$name])){
            return $cookies[$name];
        } else {
            return null;
        }
    }

    public static function get_cookies(){
        if(isset($_COOKIE[self::$cookie_key])){
            return json_decode($_COOKIE[self::$cookie_key], true);
        } else {
            return null;
        }
    }

    /**
     * @param mixed $value set to 'null' to delete
     */
    public static function set_cookies($arr){
        $cookies = self::get_cookies();
        foreach($arr as $name => $value){
            if($value === null){
                unset($cookies[$name]);
            } else {
                $cookies[$name] = $value;
            }
            setcookie(self::$cookie_key, json_encode($cookies), 0, '/');
            $_COOKIE[self::$cookie_key] = $cookies;
        }
    }

    public static function error($msg = '', $redirect = false){
        $err = 'session error: '. $msg;
        error_log($err);
        echo htmlspecialchars($err);

        if($redirect){
            header('Location: /?action=login&e='.urlencode($msg));
        }

        exit;
    }
}

